﻿// ===============================================================================
// 西交投Windows窗体应用程序开发平台 版权所有
// ===============================================================================

using DevExpress.Images;
using DevExpress.Utils;
using DevExpress.XtraBars;
using DevExpress.XtraBars.Docking2010.Views;
using DevExpress.XtraBars.Docking2010.Views.Tabbed;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using XCI.Core;
using XCI.Helper;
using XCI.Service;
using XCI.Sys.Forms;
using XCI.Sys.Model;
using XCI.Sys.Service;
using XCI.Windows;

namespace XCI.Sys.Helper
{
    public class MainFormManager
    {
        private readonly Dictionary<string, BaseDocument> documents = new Dictionary<string, BaseDocument>();
        //private MdiClient client = this.mainForm.Controls.OfType<MdiClient>().FirstOrDefault();
        private readonly Stopwatch sw = new Stopwatch();
        private readonly IMainForm main;
        private readonly TabbedView tabbedView;
        private readonly bool menuLargeIcon;
        private SimpleTimer dateTimer;
        private SimpleTimer activeUserTimer;

        public MainFormManager(IMainForm main, TabbedView tabbedView, bool menuLargeIcon)
        {
            this.main = main;
            this.tabbedView = tabbedView;
            this.menuLargeIcon = menuLargeIcon;
            main.OwnForm.FormClosing += async (o, e) =>
            {
                if (MessageBoxHelper.ShowMessageYesNo("您确定要退出吗？") != DialogResult.Yes)
                {
                    e.Cancel = true;
                }
                else if (SysApp.CurrentUser != null)
                {
                    await SysAccountService.Instance.LogoutAsync(SysApp.CurrentUser.Id);
                }
            };

            tabbedView.DocumentAdded += TabbedView_DocumentAdded;
            tabbedView.DocumentClosing += TabbedView_DocumentClosing;

            main.OwnForm.Text = App.Setting.Name;
            if (App.Setting.EnableSyncDateTime)
            {
                TimerHelper.TimerRun("syncDate", 1000 * 60 * 60, () => { App.Handler.SyncDateTime(null); });
            }
        }

        private void TabbedView_DocumentAdded(object sender, DocumentEventArgs e)
        {
            if (e.Document.Control?.Tag != null)
            {
                string code = e.Document.Control.Tag.ToString();
                if (!documents.ContainsKey(code))
                {
                    var currentModel = SysApp.GetCurrentUserOwnModules().FirstOrDefault(p => p.Code.Equals(code));
                    if (currentModel != null)
                    {
                        var imageName = currentModel.WinCls;
                        if (!string.IsNullOrEmpty(imageName))
                        {
                            imageName = menuLargeIcon ? imageName.Replace("16x16", "32x32") : imageName.Replace("32x32", "16x16");
                            var img = ImageResourceCache.Default.GetImage(imageName) ?? ImageResourceCache.Default.GetImage(currentModel.WinCls);
                            e.Document.Image = img ?? (menuLargeIcon ? R.DefaultModuleImage32 : R.DefaultModuleImage16);
                        }
                    }
                    documents.Add(code, e.Document);
                }
                if (code.Equals(R.MainFormHomePageCode) && e.Document is Document homeDoc)
                {
                    e.Document.Image = menuLargeIcon ? R.MainFormHomePageHome32 : R.MainFormHomePageHome16;
                    homeDoc.Properties.AllowClose = DevExpress.Utils.DefaultBoolean.False;
                    homeDoc.Properties.AllowFloatOnDoubleClick = DefaultBoolean.False;
                    homeDoc.Properties.AllowFloat = DefaultBoolean.False;
                }
            }
        }

        private void TabbedView_DocumentClosing(object sender, DocumentCancelEventArgs e)
        {
            if (e.Document?.Control.Tag != null)
            {
                var code = e.Document.Control.Tag.ToString();
                documents.Remove(code);
            }
        }

        public void AddDocument(SysModule entity)
        {
            var args = new SMap();
            WinFormHelper.ResolvingFormParam(entity.Param).ForEach(p => args[p.Key] = p.Value);
            AddDocument(new FormProviderInfo
            {
                Name = entity.Name,
                Code = entity.Code,
                Provider = entity.WinUrl,
                Args = args
            });
        }

        public void AddDocument(FormProviderInfo formProviderInfo)
        {
            if (formProviderInfo == null) return;
            if (string.IsNullOrEmpty(formProviderInfo.Provider)) return;

            sw.Reset();
            sw.Start();
            var code = formProviderInfo.Code;
            var name = formProviderInfo.Name;
            var provider = formProviderInfo.Provider;
            if (documents.TryGetValue(code, out var document))
            {
                tabbedView.Controller.Activate(document);
                return;
            }

            Type type = Type.GetType(provider, false);
            if (type == null) return;

            object instance = Activator.CreateInstance(type);
            var frm = instance as BaseForm;
            if (frm == null) return;
            frm.Args = formProviderInfo.Args;

            AddDocument(new FormInfo
            {
                Code = code,
                Name = name,
                FormInstance = frm
            });
        }

        public void AddDocument(FormInfo formInfo)
        {
            if (formInfo?.FormInstance == null) return;
            if (documents.TryGetValue(formInfo.Code, out var document))
            {
                tabbedView.Controller.Activate(document);
                return;
            }

            sw.Reset();
            sw.Start();
            if (!string.IsNullOrEmpty(formInfo.Name)) formInfo.FormInstance.Text = formInfo.Name;
            if (!string.IsNullOrEmpty(formInfo.Code)) formInfo.FormInstance.Tag = formInfo.Code;

            tabbedView.AddDocument(formInfo.FormInstance);
            sw.Stop();
            main.OnMessage($"{sw.Elapsed.TotalMilliseconds:###0.##} ms");
        }

        public void InitActiveUser()
        {
            if (App.Setting.DebugMode) return;
            if (SysApp.CurrentUser == null) return;

            activeUserTimer = SimpleTimer.LoopTimer(30000, async () =>
            {
                await SysAccountService.Instance.ActiveOnlineUserAsync(SysApp.CurrentUser.Id);
            });
            activeUserTimer.Invoke();
            activeUserTimer.Start();
        }

        /// <summary>
        /// 设置主页状态信息
        /// </summary>
        public async void SetStatusInfo(BarStaticItem statusTime, BarStaticItem statusUser, BarStaticItem statusAccount,
            BarStaticItem statusDept, BarStaticItem statusOs, BarStaticItem statusServer)
        {
            if (SysApp.CurrentUser == null)
            {
                if (statusUser != null) statusUser.Caption = null;
                if (statusAccount != null) statusAccount.Caption = null;
                if (statusDept != null) statusDept.Caption = null;
            }
            else
            {
                if (statusUser != null) statusUser.Caption = SysApp.CurrentUser.Name;
                if (statusAccount != null) statusAccount.Caption = SysApp.CurrentUser.Account;
                if (statusDept != null) statusDept.Caption = SysApp.CurrentUser.DeptName;
            }
            if (statusOs != null)
            {
                statusOs.Caption = App.ClientOsName;
            }
            if (statusServer != null)
            {
                var clientIp = await CoreService.Instance.ClientIpAsync();
                var fileServer = App.Setting.FileServer ?? App.Setting.Server;
                var serverUrl = App.Setting.Server.BaseUrl;
                var fileServerUrl = fileServer.BaseUrl;
                statusServer.Caption = serverUrl;
                var sTooltip = new SuperToolTip();
                var args = new SuperToolTipSetupArgs();
                args.Contents.Text = $"<b>网络地址：</b><br>{clientIp}<br>" +
                                     $"<b>服务器：</b><br>{serverUrl}<br>" +
                                     $"<b>文件服务器：</b><br>{fileServerUrl}";
                args.ShowFooterSeparator = false;
                args.AllowHtmlText = DefaultBoolean.True;
                sTooltip.Setup(args);
                statusServer.SuperTip = sTooltip;

                statusServer.ItemDoubleClick += (o, e) =>
                {
                    Clipboard.SetDataObject($"网络地址：{clientIp}\n服务器：{serverUrl}\n文件服务器：{fileServerUrl}", true);
                };
            }
            if (statusTime != null)
            {
                dateTimer = SimpleTimer.LoopTimer(1000, () =>
                {
                    statusTime.Caption = DateTimeHelper.FormatDateHasSecond(DateTime.Now);
                });
                dateTimer.Invoke();
                dateTimer.Start();
            }
        }

        /// <summary>
        /// 创建主页
        /// </summary>
        public void ShowHomeDocument()
        {
            var frmHome = SysApp.Handler.CreateHomeForm();
            if (frmHome != null)
            {
                frmHome.Tag = R.MainFormHomePageCode;
                frmHome.MdiParent = main.OwnForm;
                frmHome.Show();
            }
        }

        public async void SwitchUser()
        {
            if (MessageBoxHelper.ShowMessageYesNo("您确定要退出，更换其他账号登陆吗？") != DialogResult.Yes) return;
            if (SysApp.CurrentUser != null) await SysAccountService.Instance.LogoutAsync(SysApp.CurrentUser.Id);
            Startup.Restart();
        }

        public void LockUser()
        {
            var mform = main.OwnForm;
            mform.Hide();
            var frm = new FrmUnLock();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                mform.Show();
                if (mform.WindowState != FormWindowState.Maximized)
                {
                    mform.WindowState = FormWindowState.Maximized;
                }
            }

            frm.Dispose();
        }

        public void ShowThemeForm()
        {
            var frm = new FrmSettingThemeForm();
            frm.ShowDialog();
            frm.Dispose();
        }

        public void ShowModifyPasswordForm()
        {
            var frm = new FrmModifyPassword();
            frm.ShowDialog();
            frm.Dispose();
        }

        public void ShowAboutForm()
        {
            var frmAbout = SysApp.Handler.CreateAboutForm();
            if (frmAbout != null)
            {
                frmAbout.ShowDialog();
                frmAbout.Dispose();
            }
        }
    }
}